package cn.cj.erp.modules.system.controller;

import cn.cj.erp.bo.system.SysRoleBo;
import cn.cj.erp.common.constants.SystemConstants;
import cn.cj.erp.common.excel.util.ExcelUtil;
import cn.cj.erp.common.exception.ServiceException;
import cn.cj.erp.common.security.security.service.PermissionService;
import cn.cj.erp.common.security.security.user.LoginUser;
import cn.cj.erp.common.security.security.utils.SecurityUtils;
import cn.cj.erp.common.utils.ServletUtils;
import cn.cj.erp.common.utils.UserUtils;
import cn.cj.erp.modules.common.controller.AbstractController;
import cn.cj.erp.service.system.SysRoleMenuService;
import cn.cj.erp.service.system.SysRoleService;
import cn.cj.erp.common.security.annotation.Log;
import cn.cj.erp.common.enums.LogBusinessTypeEnum;
import cn.cj.erp.common.Page;
import cn.cj.erp.common.http.Result;
import cn.cj.erp.service.system.SysUserRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;

/**
 * 角色管理
 *
 * @author chenjian
 */
@Validated
@RestController
@Slf4j
@RequestMapping("/system/role")
public class SysRoleController extends AbstractController {
    @Resource
    private PermissionService permissionService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysRoleMenuService sysRoleMenuService;

    /**
     * 角色列表
     */
    @PostMapping("/list")
    @PreAuthorize("@ss.hasPerm('system:role:list')")
    public Result<Page<SysRoleBo>> list(@RequestBody SysRoleBo params) {
        return Result.query(sysRoleService.queryPage(params));
    }

    /**
     * 角色信息
     */
    @GetMapping("/info/{roleId}")
    @PreAuthorize("@ss.hasPerm('system:role:query')")
    public Result<SysRoleBo> info(@PathVariable("roleId") Long roleId) {
        return Result.query(sysRoleService.getById(roleId));
    }

    /**
     * 保存、更新多个角色
     */
    @PostMapping("/batchSaveRole")
    @PreAuthorize("@ss.hasAnyPerm('system:role:add,system:role:edit')")
    @Log(title = "角色管理", businessType = LogBusinessTypeEnum.INSERT)
    public Result<Boolean> batchSaveRole(@Valid @RequestBody SysRoleBo[] sysRoles) {
        return Result.save(sysRoleService.saveBatch(Arrays.asList(sysRoles)));
    }

    /**
     * 删除多个角色
     */
    @PostMapping("/batchDeleteRole")
    @PreAuthorize("@ss.hasAnyPerm('system:role:remove')")
    @Log(title = "角色管理", businessType = LogBusinessTypeEnum.DELETE)
    public Result<Boolean> batchDeleteRole(@Valid @RequestBody SysRoleBo[] sysRoles) {
        return Result.remove(sysRoleService.batchDeleteRole(Arrays.asList(sysRoles)));
    }

    @Log(title = "角色管理", businessType = LogBusinessTypeEnum.EXPORT)
    @PreAuthorize("@ss.hasPerm('system:role:export')")
    @PostMapping("/export")
    public void export(@RequestBody SysRoleBo params) {
        List<SysRoleBo> list = sysRoleService.queryList(params);
        ExcelUtil.exportExcel(SysRoleBo.class, list, ServletUtils.getResponse(), "角色数据");
    }

    @PreAuthorize("@ss.hasPerm('system:role:edit')")
    @Log(title = "用户角色管理", businessType = LogBusinessTypeEnum.UPDATE)
    @PostMapping("/addRoleUser/{roleId}/{userIds}")
    public Result<Boolean> addRoleUser(@PathVariable("roleId") Long roleId, @PathVariable("userIds") Long[] userIds) {
        return Result.save(sysUserRoleService.saveUsersToRole(roleId, Arrays.asList(userIds)));
    }

    /**
     * 删除角色下选中用户
     */
    @PreAuthorize("@ss.hasPerm('system:role:remove')")
    @Log(title = "角色管理", businessType = LogBusinessTypeEnum.DELETE)
    @PostMapping("deleteRoleUser/{roleId}/{userIds}")
    public Result<Boolean> deleteRoleUser(@PathVariable("roleId") Long roleId, @PathVariable("userIds") Long[] userIds) {
        return Result.remove(sysUserRoleService.removeUsersFromRole(roleId, Arrays.asList(userIds)));
    }

    @PreAuthorize("@ss.hasPerm('system:role:edit')")
    @Log(title = "角色菜单管理", businessType = LogBusinessTypeEnum.UPDATE)
    @PostMapping("/addRoleMenu")
    public Result<Boolean> addRoleMenu(@RequestBody SysRoleBo sysRole) {
        if (SystemConstants.SUPER_ROLE.equals(sysRole.getRoleId())) {
            throw new ServiceException("不允许操作超级管理员角色");
        }
        boolean result = sysRoleMenuService.saveAllMenusToRole(sysRole.getRoleId(), sysRole.getMenuIds());
        if (!result) {
            throw new ServiceException("保存角色的菜单失败");
        }

        LoginUser loginUser = SecurityUtils.getLoginUser();
        // 更新缓存用户权限
        if (loginUser.getUser() != null && !UserUtils.isAdmin(loginUser.getUserId())) {
            loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
            tokenService.setLoginUser(loginUser);
        }
        return Result.ok();
    }

    @PreAuthorize("@ss.hasPerm('system:role:edit')")
    @Log(title = "角色权限管理", businessType = LogBusinessTypeEnum.UPDATE)
    @PostMapping("/authDataScope")
    public Result<Boolean> authDataScope(@RequestBody SysRoleBo sysRole) {
        return Result.ok(sysRoleService.authDataScope(sysRole));
    }
}
